﻿
#include <future>
#include <mutex>
#include <cmath>
#include <math.h>
#include "picDeal.h"
#include "everyClass.h"
#include "zero_threadpool.h"
using namespace std;
long base_shape::m_nCols = 140000;//------文件列数
long base_shape::m_nRows = 300000;//------文件行数
long base_shape::m_SRows = 1000;
int base_shape::m_FileCount = 0;
FILE* base_shape::m_fp = nullptr;
byte** base_shape::m_PicA = nullptr;
byte** base_shape::m_PicB = nullptr;
std::mutex mu;

int main()
{
	clock_t start, end;//定义clock_t变量
	srand(time(nullptr));
	char filePath[] = "E://缩放星星全息Big.DFF";
	double reso = 0.5;
	base_shape::write_File(filePath, reso);
	double change = 2000;

	//------------------------------------------------------------
	int cpuNum = 20;
	BYTE*** pic = new BYTE * *[cpuNum];
	point* pLB = new point[cpuNum];
	int* picSide = new int[cpuNum];
	bool* T = new bool[cpuNum];
	ZERO_ThreadPool threadpool;
	threadpool.init(cpuNum);
	threadpool.start(); //------------------ 启动线程池
	double cirR = 30 * (change / 2000);
	double dist = 30 * (change / 2000);
	int suitPicw = base_shape::m_nCols / (2 * dist);
	int suitPich = base_shape::m_nRows / (2 * dist);
	int writeNum = int(suitPicw / cpuNum) + 1;
	suitPicw = writeNum * cpuNum;
	//===========================================
	vector<double>** GridAngel = new vector<double> * [suitPich];
	int** maxGG = new int* [suitPich];
	double** movecirR = new double* [suitPich];
	Vec baseV = { 1,0 };
	for (int i = 0; i < suitPich; i++) {
		GridAngel[i] = new vector<double>[suitPicw];
		maxGG[i] = new int[suitPicw] { 0 };
		movecirR[i] = new double[suitPicw];
	}
	//===========================================
	vector<point> allCenterPoint, allSmallCenterPoint;
	const string pointBasePath = "D://个人资料//xfw测试//空间点//星星手动点.txt";
	readPointsFromFile(pointBasePath, allCenterPoint, allSmallCenterPoint);
	//---------------------------------------------------------------------------
	vector<point> Base_BigStarPoint;
	char pointPath[] = "D://个人资料//xfw测试//空间点//星星基础点.txt";
	getPoint(pointPath, Base_BigStarPoint);
	//---------------------------------------------------------------------------
	point pBigStarCenter = { 6.85815,6.61266 };

	for (int q = 0; q < allCenterPoint.size(); q++) {
		vector<point> BigStarPoint;
		Vec MoveStarV = allCenterPoint[q] - pBigStarCenter;
		for (int i = 0; i < Base_BigStarPoint.size(); i++) {
			point P = Base_BigStarPoint[i] + MoveStarV;
			BigStarPoint.push_back(P);
		}
		//------------------------------------------------------------------------
		Vec moveSeg = allSmallCenterPoint[q] - allCenterPoint[q];
		point pSmallStarCenter = allCenterPoint[q] + moveSeg;
		//double maxDist = (allCenterPoint[q] - pCirCenter).abs() * change;//以中心点到页面圆心的距离作为最大距离
		//point changeCirCenter = pCirCenter * change;
		vector<point> SmallStarPoint;
		for (int i = 0; i < BigStarPoint.size(); i++) {
			point P = BigStarPoint[i] + moveSeg;//先移动
			//P = pSmallStarCenter + (P - pSmallStarCenter) * 0.1;//再缩放
			// 分别计算x和y方向的缩放，使用不同的缩放系数
			double scaleX = 0.15; // x方向的缩放比例，可以根据需要修改
			double scaleY = 0.3; // y方向的缩放比例，可以根据需要修改

			// 先将点相对于中心点进行均匀缩放（保持形状）
			double uniformScale = sqrt(scaleX * scaleY); // 使用几何平均数作为均匀缩放系数

			// 应用均匀缩放，保持花瓣形状
			P.x = pSmallStarCenter.x + (P.x - pSmallStarCenter.x) * uniformScale;
			P.y = pSmallStarCenter.y + (P.y - pSmallStarCenter.y) * uniformScale;

			// 最后应用x和y方向的拉伸比例
			P.x = pSmallStarCenter.x + (P.x - pSmallStarCenter.x) * (scaleX / uniformScale);
			P.y = pSmallStarCenter.y + (P.y - pSmallStarCenter.y) * (scaleY / uniformScale);

			//BigStarPoint[i] = P; // 别忘了保存结果
			//--------改比例------------
			P = P * change;
			SmallStarPoint.push_back(P);
			BigStarPoint[i] = BigStarPoint[i] * change;
		}
		//-------------------------------------------------------------------------
		for (int i = 0; i < BigStarPoint.size(); i++) {
			int nLayers = int(3 * (BigStarPoint[i] - SmallStarPoint[i]).abs());
			int stepJ =  int(0.01 * nLayers);
			int Num = nLayers / stepJ;
			for (int j = 0; j <= nLayers; ++j) {
				//int Mod = j % stepJ;
				//int Mod = int(j / stepJ) % 2;
				int ModJ = j - int(j / stepJ) * stepJ;
				double c = double(j) / nLayers;
				int changeWidJ = stepJ * (0.2 + 0.8 * (1 - c));
				if (ModJ==0) {
					//计算此时的中心点
					point P_pCenter = (allCenterPoint[q] + (pSmallStarCenter - allCenterPoint[q]) * c) * change;
					point P = BigStarPoint[i] + (SmallStarPoint[i] - BigStarPoint[i]) * c;
					int nSegs = int(2 * (P_pCenter - P).abs()/(2*dist));
					double distC = 1 - c;
					int Gray = distC * distC * distC * 255;
					//double angel = -PI / 2 + PI * c;
					double angel = -PI / 2 + 1.5*PI * int(j / stepJ) / (Num-1);
					for (int t = 0; t <= nSegs; t++) {
						double tc = double(t) / nSegs;
						point starInnerP = P + (P_pCenter - P) * tc;
						int Gi = int(starInnerP.y / (2 * dist)), Gj = int(starInnerP.x / (2 * dist));
						if (Gi >= 0 && Gi < suitPich && Gj >= 0 && Gj < suitPicw) {
							auto& vec = GridAngel[Gi][Gj];
							if (vec.empty()) {
								vec.push_back(angel); // 第一个
							}
							else if (vec.size() == 1) {
								if (angel != vec[0]) {
									// 插入后手动排序，确保 vec[0] 是 min，vec[1] 是 max
									if (angel < vec[0]) {
										vec.push_back(vec[0]); // 原来的移到后面
										vec[0] = angel;
									}
									else {
										vec.push_back(angel);
									}
								}
							}
							else {
								// 已有两个值，vec[0] 是 min，vec[1] 是 max
								vec[0] = min(vec[0], angel);
								vec[1] = max(vec[1], angel);
							}
							if(Gray>maxGG[Gi][Gj])
								maxGG[Gi][Gj] =  Gray;
						}
					}
					
				}
			}
		}
		printf("\r生成中[%.2lf%%]:", ((q + 1)) * 100.0 / (allCenterPoint.size()));
		//==============================================
	}
	for (long i = 0; i < suitPich; i++) {
		double y = dist + 2 * dist * i;
		for (long j = 0; j < writeNum; j++) {
			class std::future<unsigned char* __ptr64* __ptr64>* pF = new class std::future<unsigned char* __ptr64* __ptr64>[cpuNum];
			cirLine** cL = new cirLine * [cpuNum];
			for (int n = 0; n < cpuNum; n++) {
				long xIndex = j * cpuNum + n;
				double x = dist + xIndex * 2 * dist;
				point pCenter = { x,y };
				double minAngel = 0;
				double maxAngel = 0;
				long picCount = i * suitPicw + xIndex;
				//double c = dR.pic()[picCount] / 255.0;
				T[n] = false;
				int Gray = 0;
				if (!GridAngel[i][xIndex].empty()) {
					minAngel = *min_element(GridAngel[i][xIndex].begin(), GridAngel[i][xIndex].end());
					maxAngel = *max_element(GridAngel[i][xIndex].begin(), GridAngel[i][xIndex].end());
					T[n] = true;
					Gray = maxGG[i][xIndex];
				}
				else {
					minAngel = PI / 2, maxAngel = PI / 2;
				}
				/*double realCirR = cirR * c;
				int maxG = 254 * c;*/
				cL[n] = new cirLine(pCenter, minAngel, maxAngel, cirR, Gray);
			}
			for (int n = 0; n < cpuNum; n++) {
				pF[n] = threadpool.exec(std::bind(&cirLine::make_Rec, cL[n],
					std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), ref(pLB[n]), T[n], ref(picSide[n]));
			}
			threadpool.waitForAllDone();
			int side = int(2 * cirR);
			for (int t = 0; t < cpuNum; t++) {
				pic[t] = pF[t].get();
				for (int m = 0; m < picSide[t]; m++) {
					for (int n = 0; n < picSide[t]; n++) {
						point P = { pLB[t].x + n,pLB[t].y + m };
						int Gray = pic[t][m][n];
						long iRow = int(P.y), iCol = int(P.x);
						if (iRow >= 0 && iRow < base_shape::m_nRows && iCol >= 0 && iCol < base_shape::m_nCols) {
							long fileRows = iRow - base_shape::m_FileCount * base_shape::m_SRows;
							if (fileRows < base_shape::m_SRows)
							{
								if (base_shape::m_PicA[fileRows][iCol] < Gray)
									base_shape::m_PicA[fileRows][iCol] = Gray;
							}
							else if (fileRows >= base_shape::m_SRows)
							{

								if (base_shape::m_PicB[fileRows - base_shape::m_SRows][iCol] < Gray)
									base_shape::m_PicB[fileRows - base_shape::m_SRows][iCol] = Gray;
							}
						}
					}
				}
				delete cL[t];
				cL[t] = nullptr;
			}
			delete[] pF; pF = nullptr;
			delete[] cL; cL = nullptr;
		}
		if (y - base_shape::m_FileCount * base_shape::m_SRows > 1.5 * base_shape::m_SRows) {
			base_shape::fresh_File();
		}
		printf("\r生成中[%.2lf%%]:", ((i + 1)) * 100.0 / (suitPich));
	}
	base_shape::close_File();
	std::cin.get();
	//
	return 0;
}
